# include "../include/Formater.h"
# include "../include/Logger.h"
# include <regex>

ZDSJ::Formater::Formater()
{
	this->m_formater = new std::string("{}");
	this->m_payload = new std::vector<ZDSJ::Support>();
	this->dealFormat();
}

ZDSJ::Formater::Formater(const std::string& _formater)
{
	this->m_formater = new std::string(_formater);
	this->m_payload = new std::vector<ZDSJ::Support>();
	this->dealFormat();
}

ZDSJ::Formater::Formater(const Formater& _other)
{
	delete this->m_formater;
	delete this->m_payload;
	this->m_formater = new std::string(*_other.m_formater);
	this->m_payload = new std::vector<ZDSJ::Support>();
	this->dealFormat();
}

ZDSJ::Formater& ZDSJ::Formater::operator=(const Formater& _other)
{
	delete this->m_formater;
	delete this->m_payload;
	this->m_formater = new std::string(*_other.m_formater);
	this->m_payload = new std::vector<ZDSJ::Support>();
	this->dealFormat();
	return *this;
}

ZDSJ::Formater::~Formater()
{
	delete this->m_formater;
	delete this->m_payload;
}

void ZDSJ::Formater::dealFormat()
{
	const std::vector<std::string>& support = Logger::getInstance()->getSupport();
	std::string result(*this->m_formater);
	std::regex reg(R"(\[%([^\]]*?)%\])");
	std::smatch match;
	std::vector<std::tuple<std::string, std::tuple<size_t, size_t>>> matches;
	size_t match_index = 0;
	int index = 0;
	std::string temp;
	std::string::const_iterator start = result.cbegin();
	std::string::const_iterator end = result.cend();
	while (std::regex_search(start, end, match, reg)) {
		start = match.suffix().first;
		match_index += match.position();
		std::string match_str = match[1];
		matches.push_back(std::make_tuple(match_str, std::make_tuple(match_index, match_str.size() + 4)));
		match_index += match_str.size() + 4;
	}
	for (auto iter = matches.rbegin(); iter != matches.rend(); ++iter) {
		result.erase(std::get<0>(std::get<1>(*iter)), std::get<1>(std::get<1>(*iter)));
		for (int i = 0; i < support.size(); ++i) {
			index = std::get<0>(*iter).find(support.at(i));
			if (index != std::string::npos) {
				temp = std::get<0>(*iter);
				temp.erase(index, support.at(i).size());
				temp.insert(index, "{}");
				this->m_payload->push_back(Support(i));
			}
		}
		result.insert(std::get<0>(std::get<1>(*iter)), temp);
	}
	std::reverse(this->m_payload->begin(), this->m_payload->end());
	delete this->m_formater;
	this->m_formater = new std::string(result);
}
